﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Intrinsics.Arm;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Threading;

namespace Huioo.Learning.WPF.Client.Views
{
    public class RandomExtension : MarkupExtension
    {
        static readonly Random _rnd = new Random();

        readonly int _from, _to;

        public RandomExtension(int from, int to)
        {
            _from = from; _to = to;
        }

        public RandomExtension(int to)
           : this(0, to)
        {
        }

        /// <summary>
        /// 使用分数值，而非默认整数
        /// </summary>
        public bool UseFractions { get; set; }

        /// <summary>
        /// 允许按规则间隔修改属性值
        /// </summary>
        public TimeSpan UpdateInterval { get; set; }

        //public override object ProvideValue(IServiceProvider sp)
        //{
        //    return (double)_rnd.Next(_from, _to);
        //}

        //public override object ProvideValue(IServiceProvider sp)
        //{
        //    //int value = _rnd.Next(_from, _to);
        //    double value = UseFractions ?
        //        _rnd.NextDouble() * (_to - _from) + _from :
        //        (double)_rnd.Next(_from, _to);
        //    Type targetType = null;
        //    if (sp != null)
        //    {
        //        var target = sp.GetService(typeof(IProvideValueTarget))
        //           as IProvideValueTarget;
        //        if (target != null)
        //        {
        //            var clrProp = target.TargetProperty as PropertyInfo;
        //            if (clrProp != null)
        //                targetType = clrProp.PropertyType;
        //            if (targetType == null)
        //            {
        //                var dp = target.TargetProperty
        //                   as DependencyProperty;
        //                if (dp != null)
        //                    targetType = dp.PropertyType;
        //            }
        //        }
        //    }
        //    return targetType != null ?
        //       Convert.ChangeType(value, targetType) :
        //       value.ToString();
        //}

        public override object ProvideValue(IServiceProvider sp)
        {
            //int value = _rnd.Next(_from, _to);
            double value = UseFractions ?
                _rnd.NextDouble() * (_to - _from) + _from :
                (double)_rnd.Next(_from, _to);

            Type targetType = null;
            if (sp != null)
            {
                var target = sp.GetService(typeof(IProvideValueTarget))
                   as IProvideValueTarget;
                if (target != null)
                {
                    var pi = target.TargetProperty as PropertyInfo;
                    if (pi != null)
                        targetType = pi.PropertyType;
                    if (targetType == null)
                    {
                        var dp = target.TargetProperty
                           as DependencyProperty;
                        if (dp != null)
                            targetType = dp.PropertyType;
                    }

                    //if (UpdateInterval != TimeSpan.Zero)
                    //{
                    //    object finalValue = null;
                    //    // setup timer...
                    //    var timer = new DispatcherTimer();
                    //    timer.Interval = UpdateInterval;
                    //    timer.Tick += (sender, e) => {
                    //        value = UseFractions ?
                    //            _rnd.NextDouble() * (_to - _from) + _from :
                    //            (double)_rnd.Next(_from, _to);
                    //        finalValue = targetType != null ?
                    //            Convert.ChangeType(value, targetType) :
                    //            value.ToString();

                    //        var targetObject = target.TargetObject; // throw null reference exception

                    //        var dp = target.TargetProperty as DependencyProperty;
                    //        var pi = target.TargetProperty as PropertyInfo;
                    //        if (dp != null)
                    //            ((DependencyObject)targetObject).SetValue(
                    //               dp, finalValue);
                    //        else if (pi != null)
                    //            pi.SetValue(targetObject, value, null);
                    //    };
                    //    timer.Start();
                    //}
                }
            }

            return targetType != null ?
               Convert.ChangeType(value, targetType) :
               value.ToString();


        }

    }
}
